import MSLogger
import MSData
import MSConfig
import MSReaders
import MSDBMgr_MySQL
import MSDBMgr_Firebird
from pdb import set_trace

#TBD lastEventId is ambigious now - should be solved by having an .env file with actual parameters
class MSProcessor:
    def __init__(self):
        #main dict keeping all the supported objects
        #each object has its own recent storage and pending event queue
        self.objects = {}
        self.lastEventId = 0

        #local storage
        self.storageRoot = None
        self.storage = None

        #direct database aliases
        self.dbFirebirdStaticParams = None
        self.dbMySQLStaticParams = None
        self.dbMySQLMobileParams = None

        self.dbFirebirdStatic = None
        self.dbMySQLStatic    = None
        self.dbMySQLMobile    = None

        #remote processor alias
        self.msProcessors = None

    def removeObject(self, Object):
        if self.objects.has_key(Object.objectId):
            self.objects.pop(Object.objectId)

    def addObject(self, Object):
        self.removeObject(Object)
        self.objects[Object.objectId] = Object

    def addConstructObject(self, ObjID, ObjName, ObjSkey, ObjHasStatic, ObjHasContactId, ObjHasMobile, ObjStorageRoot):
        o = MSData.MSObject(ObjID)
        o.objectName = ObjName
        o.objectSkey = ObjSkey
        o.isStatic = ObjHasStatic
        o.isContactId = ObjHasContactId
        o.isMobile = ObjHasMobile
        o.storageRoot = ObjStorageRoot
        self.addObject(o)

    #should be called after creation to init correct event id
    def initLastEventId(self):
        prevLastEventId = self.lastEventId
        try:
            prevLastEventId = self.lastEventId
            for o in self.objects.values():
                o.openEventStorage()
                if o.eventStorage != None:
                    maxObjKey = o.eventStorage.keys()[len(o.eventStorage.keys())-1]
                    if maxObjKey > self.lastEventId:
                        self.lastEventId = maxObjKey
        except (Exception), err:
            MSLogger.logError('failed to init last event id with error: %s' % str(err))
            self.lastEventId = prevLastEventId

    def readEvents(self):
        for o in self.objects.values():
            eventsInQueueBefore = len(o.pendingEvents)
            if o.isStatic:
                self.lastEventId = MSReaders.readStaticPGSMEvents(o, int(self.lastEventId))
            if o.isContactId:
                self.lastEventId = MSReaders.readStaticContactIdEvents(o, self.lastEventId)
            if o.isMobile:
                self.lastEventId = MSReaders.readMobileEvents(o, self.lastEventId)
            #if there is smth new we update last event
            if eventsInQueueBefore < len(o.pendingEvents):
                o.lastEvent = o.pendingEvents[len(o.pendingEvents)-1]

    def storeEvents(self):
        for o in self.objects.values():
            if self.dbFirebirdStaticParams != None:
                p = self.dbFirebirdStaticParams
                self.dbFirebirdStatic = MSDBMgr_Firebird.storeStaticEvents(o.pendingEvents,
                                                                           self.dbFirebirdStatic,
                                                                           p[0], p[1], p[2])
            if self.dbMySQLStaticParams != None:
                p = self.dbMySQLStaticParams
                self.dbMySQLStatic = MSDBMgr_MySQL.storeStaticEvents(o.pendingEvents,
                                                                     self.dbMySQLStatic,
                                                                     p[0], p[1], p[2], p[3])

            if self.dbMySQLMobileParams != None:
                p = self.dbMySQLMobileParams
                self.dbMySQLMobile = MSDBMgr_MySQL.storeMobileEvents(o.pendingEvents,
                                                                     self.dbMySQLMobile,
                                                                     p[0], p[1], p[2], p[3])

    def dropQueues(self):
        for o in self.objects.values():
            if o.pendingEventsDone:
                o.pendingEvents = []

    def readConfig(self, ProcessorCfg, ObjectsCfg):
        if ProcessorCfg != None:
            MSConfig.readProcessorConfig(self, ProcessorCfg)
        if ObjectsCfg != None:
            MSConfig.readObjectsConfig(self, ObjectsCfg)
